package com.lagou.edu.controller;

import com.lagou.edu.pojo.Auth;
import com.lagou.edu.service.CodeService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Random;

@RestController
@RequestMapping("/code")
public class CodeController {
    @Autowired
    private CodeService codeService;

    /**
     * ⽣成验证码并发送到对应邮箱，成功true，失败
     * false
     */
    @RequestMapping("/create/{email}")
    public Boolean create(
            @PathVariable("email") String email) {
        return codeService.createCode(email);
    }

    /**
     * 校验验证码是否正确，0正确1错误2超时
     * <p>
     * 提供者模拟处理超时，调用方法添加Hystrix控制
     * 使用@HystrixCommand注解进行熔断控制
     */
    @HystrixCommand(
            // 线程池标识，要保持唯一，不唯一的话就共用了
            threadPoolKey = "validate",
            // 线程池细节属性配置
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "1"), // 线程数
                    @HystrixProperty(name = "maxQueueSize", value = "20") // 等待队列长度
            },
            // commandProperties熔断的一些细节属性配置
            commandProperties = {
                    // 每一个属性都是一个HystrixProperty
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
            },
            fallbackMethod = "myFallBack"  // 回退方法
    )
    @RequestMapping("/validate/{email}/{code}")
    public Integer validate(
            @PathVariable("email") String email,
            @PathVariable("code") String code) {
        // 随机超时
        try {
            Random random = new Random();
            int ran = random.nextInt(10);
            ran = ran * 1000;
            System.out.println("睡眠时间是：" + ran);
            Thread.sleep(ran);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("-------------------->睡眠结束");

        List<Auth> aList = codeService.findByEmailAndCode(email, code);
        if (aList == null || aList.size() == 0) {
            return 1;
        } else if (aList.size() > 0) {
            return 0;
        }
        return 2;
    }

    /**
     * 定义回退方法，返回预设默认值
     * 注意：该方法形参和返回值与原始方法保持一致
     * 0正确1错误2超时
     */
    public Integer myFallBack(String email, String code) {
        System.out.println("---------------->调用熔断函数<----------------");
        return 2; // 兜底数据
    }

}
